//    Copyright 2013 Serge Kosachiov.
//    This file is part of bulkmail-jsf.
//
//    BulkMail is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    BulkMail is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with BulkMail.  If not, see <http://www.gnu.org/licenses/>.


package bulkmail;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.logging.Logger;

import javax.faces.model.SelectItem;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchResult;

public class LdapBean {
	
	protected Logger logger = Logger.getLogger(this.getClass().getName());

	public List<String> selectedGroups;
	public List<SelectItem> listGroups;
	public Map<String, String> mapUsers;
	
	
	private String mail = "";
	

	public String getEmail() {
		return mail;
	}

	public void setEmail(String email) {
		this.mail = email;
	}

	//

	public List<String> getSelectedGroups() {
	 	return selectedGroups;
	}
	public void setSelectedGroups(List<String> selectedGroups) {
	 	this.selectedGroups = selectedGroups;
	}

	
	public List<SelectItem> getListGroups() {
	 	return listGroups;
	}
	
	
	public LdapBean() {
		
		listGroups = new ArrayList<SelectItem>();
		mapUsers = new HashMap<String, String>();
				
		try {
			Properties prop = new Properties();
			prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties"));
				
			// Set up the environment for creating the initial context
			Hashtable<String, String> env = new Hashtable<String, String>();
			env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
			env.put(Context.PROVIDER_URL, prop.getProperty("PROVIDER_URL"));
			env.put(Context.SECURITY_AUTHENTICATION, prop.getProperty("SECURITY_AUTHENTICATION"));
			env.put(Context.SECURITY_PRINCIPAL, prop.getProperty("SECURITY_PRINCIPAL"));
			env.put(Context.SECURITY_CREDENTIALS, prop.getProperty("SECURITY_CREDENTIALS"));
			
			
			List<String> markedGroups = Arrays.asList(prop.getProperty("GROUPS_MARKED").split("\\s*,\\s*"));
			String policy = prop.getProperty("GROUPS_POLICY").trim();
			logger.info("policy: " + policy);
		

			// Create the initial context
			DirContext ctx = new InitialDirContext(env);

			// System.out.println("Connection toString: " + ctx.toString());
			Attributes matchAttrs = new BasicAttributes(true);
			matchAttrs.put(new BasicAttribute(prop.getProperty("GROUP_DESC")));
			matchAttrs.put(new BasicAttribute(prop.getProperty("GROUP_CN")));
			matchAttrs.put(new BasicAttribute(prop.getProperty("USER_GID")));
			NamingEnumeration<SearchResult> answer =
					ctx.search(prop.getProperty("GROUP_BASE"),
					matchAttrs);
			while (answer.hasMore()) {
				SearchResult sr = (SearchResult) answer.next();
	            Attribute attributeDesc = sr.getAttributes().get(prop.getProperty("GROUP_DESC"));
	            Attribute attributeGid = sr.getAttributes().get(prop.getProperty("USER_GID"));
	            logger.info("get group: " + attributeGid.get() + ", " + attributeDesc.get() ); 
				SelectItem si = new SelectItem( (Object) attributeGid.get(), (String) attributeDesc.get() );
				if (policy.equals("include")) {
					logger.info("include: " + attributeGid.get());
					if (markedGroups.contains(attributeGid.get())) listGroups.add(si);
				}
				if (policy.equals("exclude")) {
					if (!markedGroups.contains(attributeGid.get())) listGroups.add(si);
				}
				
			}
			
			//
			Comparator<SelectItem> selectItemComparator = new Comparator<SelectItem>() {
				@Override
				public int compare(SelectItem arg0, SelectItem arg1) {
					return arg0.getLabel().compareTo(arg1.getLabel());
				}
			};
			java.util.Collections.sort(listGroups, selectItemComparator);
			
			//
			matchAttrs = new BasicAttributes(true);
			matchAttrs.put(new BasicAttribute(prop.getProperty("USER_GID")));
			matchAttrs.put(new BasicAttribute(prop.getProperty("USER_MAIL")));
			answer =
					ctx.search(prop.getProperty("USER_BASE"),
					matchAttrs);
			while (answer.hasMore()) {
				SearchResult sr = (SearchResult) answer.next();
	            Attribute attributeGid = sr.getAttributes().get(prop.getProperty("USER_GID"));
	            Attribute attributeMail = sr.getAttributes().get(prop.getProperty("USER_MAIL"));
	            String key = (String) attributeGid.get();
	            String value = (String) attributeMail.get();
	            String existing = mapUsers.get(key);
	            mapUsers.put(key, existing == null ? value : existing + "," + value);
			}
			// debug
			for (Entry<String, String> entry : mapUsers.entrySet()) {
				logger.info("mail list: " + entry.getKey() + ": " + entry.getValue());
			}

		} catch (NamingException ex) {
			ex.printStackTrace();
		} catch (Exception ex) {
			ex.printStackTrace();
		}

	}

	////
	
	public String submit() {
		String selectedSubmit = "";
		for (String selectedGroup : selectedGroups) {
	        logger.info("selected item: " + selectedGroup);
	        selectedSubmit += selectedGroup + " ";
	    }
		return selectedSubmit;
	}
	


}
